
#include "Hdev.h"
#include <algorithm>
#include "HalconCpp.h"
#include "HTuple.h"
#include <map>
#include <mutex>
#include <string>
#include <QString>
#include "AppDataDef.h"
#include "mtp.h"

#ifndef __APPLE__
  #include <hdevengine/HDevEngineCpp.h>
#else
  #include <HDevEngineCpp/HDevEngineCpp.h>
#endif

using namespace HalconCpp;
using namespace HDevEngineCpp;


 Hdev::Hdev()
 {}

 Hdev::Hdev(QString fileFullPath):IHalcon(fileFullPath)
 { }


 Hdev::~Hdev()
 {}

 void Hdev::GetHeightResultManual(IN HObject const& Image, IN HObject const& InRegion,
	 OUT HObject& OutRegion, HObject& OutXld,
	 IN HTuple ModelID, HTuple miniScore,
	 IN HTuple ManualBC,
	 IN HTuple Row1, HTuple Column1, HTuple Row2, HTuple Column2,
	 OUT HTuple* Height, HTuple* iResult, HTuple* iError)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(GetHeightResultManual));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ModelID), ModelID);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(miniScore), miniScore);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ManualBC), ManualBC);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(Row1), Row1);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(Column1), Column1);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(Row2), Row2);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(Column2), Column2);

		 call.Execute();

		 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
		 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));

		 *Height = ParamHandler<HTuple>::GetParameter(call, ToSTR(Height));
		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
		 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }

 }


 void Hdev::GetHeightResult1(IN HObject const& Image, IN HObject const& InRegion, 
	 OUT HObject& OutRegion, HObject& OutXld, 
	 IN HTuple ModelID, HTuple miniScore, 
	 IN HTuple ManualBC, 
	 OUT HTuple* Height, HTuple* iResult, HTuple* iError)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(GetHeightResult1));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ModelID), ModelID);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(miniScore), miniScore);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ManualBC), ManualBC);

		 call.Execute();

		 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
		 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));

		 *Height = ParamHandler<HTuple>::GetParameter(call, ToSTR(Height));
		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
		 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }

 }

 void Hdev::GetHeightResult2(IN HObject const& Image, IN HObject const& InRegion,
	 OUT HObject& OutRegion, HObject& OutXld,
	 IN HTuple ModelID, HTuple miniScore,
	 IN HTuple ManualBC,
	 OUT HTuple* Height, HTuple* iResult, HTuple* iError)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(GetHeightResult1));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ModelID), ModelID);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(miniScore), miniScore);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ManualBC), ManualBC);

		 call.Execute();

		 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
		 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));

		 *Height = ParamHandler<HTuple>::GetParameter(call, ToSTR(Height));
		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
		 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }

 }

 void Hdev::AdjustNozzleHeight(IN HObject const& Image, IN HObject const& InRegion,
	 OUT HObject& OutRegion, HObject& OutXld,
	 IN HTuple stdHeight,
	 OUT HTuple* Height, HTuple* iResult, HTuple* iError)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(AdjustNozzleHeight));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(stdHeight), stdHeight);

		 call.Execute();

		 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
		 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));

		 *Height = ParamHandler<HTuple>::GetParameter(call, ToSTR(Height));
		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
		 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }

 }

 void Hdev::GetAppearanceResult(IN HObject const& Image, IN HObject const& InRegion, 
	 OUT HObject& OutRegion, HObject& OutXld, 
	 IN HTuple miniScore,
	 IN HTuple EdgeGray, HTuple EdgeLen, HTuple EdgeW, HTuple EdgeArea,
	 IN HTuple FrontGray, HTuple FrontLen, HTuple FrontW, HTuple  FrontArea, HTuple ModelID,
	 IN HTuple DLModelHandle, HTuple DLPreprocessParam, HTuple ClassNames, HTuple ClassIDs,
	 OUT HTuple* iResult, HTuple* iError, HTuple* strResult, HTuple* BboxRow, HTuple* BboxCol)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(GetAppearanceResult));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(miniScore), miniScore);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(EdgeGray), EdgeGray);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(EdgeLen), EdgeLen);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(EdgeW), EdgeW);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(EdgeArea), EdgeArea);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(FrontGray), FrontGray);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(FrontLen), FrontLen);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(FrontW), FrontW);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(FrontArea), FrontArea);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ModelID), ModelID);

		 ParamHandler<HTuple>::SetParameter(call, ToSTR(DLModelHandle), DLModelHandle);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(DLPreprocessParam), DLPreprocessParam);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ClassNames), ClassNames);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ClassIDs), ClassIDs);

		 call.Execute();

		 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
		 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));

		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
		 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));

		 *strResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(strResult));
		 *BboxRow = ParamHandler<HTuple>::GetParameter(call, ToSTR(BboxRow));
		 *BboxCol = ParamHandler<HTuple>::GetParameter(call, ToSTR(BboxCol));
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }
 }

 void Hdev::GetShapeResult(IN HObject const& Image, IN HObject const& InRegion,
	 OUT HObject& OutRegion, HObject& OutXld,
	 IN HTuple ModelID, HTuple miniScore,
	 IN HTuple RefX, HTuple RefY, HTuple RefR,
	 IN HTuple WidthBC1, HTuple WidthBC2, HTuple WidthBC3, HTuple WidthBC4,
	 IN HTuple RBC1, HTuple RBC2, HTuple RBC3, HTuple RBC4,
	 OUT HTuple* iResult, HTuple* iError,
	 OUT HTuple* R, HTuple* Width)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(GetShapeResult));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ModelID), ModelID);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(miniScore), miniScore);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RefX), RefX);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RefY), RefY);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RefR), RefR);

		 ParamHandler<HTuple>::SetParameter(call, ToSTR(WidthBC1), WidthBC1);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(WidthBC2), WidthBC2);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(WidthBC3), WidthBC3);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(WidthBC4), WidthBC4);

		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RBC1), RBC1);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RBC2), RBC2);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RBC3), RBC3);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RBC4), RBC4);

		 call.Execute();

		 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
		 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));

		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
		 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));

		 *R = ParamHandler<HTuple>::GetParameter(call, ToSTR(R));
		 *Width = ParamHandler<HTuple>::GetParameter(call, ToSTR(Width));
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }
 }

 void Hdev::InitInferDetection(OUT HTuple* DLModelHandle, OUT HTuple* DLPreprocessParam,\
	                           OUT HTuple* ClassNames, OUT HTuple* ClassIDs,\
	                           OUT HTuple* iError)
 {
	 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(InitInferDetection));
	 HDevEngineCpp::HDevProcedureCall call(procedure);

	 call.Execute();

	 *DLModelHandle = ParamHandler<HTuple>::GetParameter(call, ToSTR(DLModelHandle));
	 *DLPreprocessParam = ParamHandler<HTuple>::GetParameter(call, ToSTR(DLPreprocessParam));
	 *ClassNames = ParamHandler<HTuple>::GetParameter(call, ToSTR(ClassNames));
	 *ClassIDs = ParamHandler<HTuple>::GetParameter(call, ToSTR(ClassIDs));
	 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
 }

 void Hdev::InferDetection(IN HObject const& Image, IN HObject const& InRegion,\
	 OUT HObject& OutRegion, HObject& OutXld,\
	 IN HTuple DLModelHandle, HTuple DLPreprocessParam,\
	 OUT HTuple* strResult, HTuple* iResult, HTuple* iError, HTuple* BboxRow, HTuple* BboxCol)
 {
	 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(InferDetection));
	 HDevEngineCpp::HDevProcedureCall call(procedure);
	 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
	 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);

	 ParamHandler<HTuple>::SetParameter(call, ToSTR(DLModelHandle), DLModelHandle);
	 ParamHandler<HTuple>::SetParameter(call, ToSTR(DLPreprocessParam), DLPreprocessParam);

	 call.Execute();
	 *strResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(strResult));
	 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
	 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
	 *BboxRow = ParamHandler<HTuple>::GetParameter(call, ToSTR(BboxRow));
	 *BboxCol = ParamHandler<HTuple>::GetParameter(call, ToSTR(BboxCol));
 }


 //ParamHandler<HObject>::SetParameter(call, ToSTR(),);
 //ParamHandler<HTuple>::SetParameter(call, ToSTR(), );
 //= ParamHandler<HObject>::GetParameter(call, ToSTR());
 //= ParamHandler<HTuple>::GetParameter(call, ToSTR());